﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WPLDB.Infrastucture.UI.ViewModelBase;
using WPLDB.DA.Interfaces.UI;
using System.ComponentModel.Composition;
using WPLDB.DA.Interfaces.UI.Base;
using WPLDB.Infrastucture.UI.Models;
using WPLDB.DA.Models.UI;
using WPLDB.DA.Models;
using Microsoft.Practices.Prism.Commands;
using WPLDB.Utility.DB;
using WPLDB.Utility.Extensions;
using System.Collections.ObjectModel;
using Microsoft.Practices.Prism.Events;
using WPLDB.Infrastucture.UI.Events;
using WPLDB.DA.Interfaces.UI.Models;

namespace WPLDB.Package.UI.ViewModel
{
    /// <summary>
    /// This View Model helps to collect the list of tables from selected database object.
    /// also it fetch the Model Namespace information.
    /// </summary>
    [Export(typeof(IChooseTablesViewModel))]
    [Export(typeof(IChooseViewModel))]
    public class ChooseTablesViewModel : ViewModelBase, IChooseTablesViewModel
    {

        #region "Variables"

        private TablesModel _model;

        [Import]
        private IChooserModel _chooserModel = null;
        #endregion

        #region "ctor"

        [ImportingConstructor]
        public ChooseTablesViewModel(IChooseTablesView view)
        {
            OnChooserLoad();
            this.View = view;
            this.View.SetViewModel(this);
        }
        #endregion

        #region "Interface Implementation"
        public DA.Interfaces.UI.Base.IBaseView View
        {
            get;
            set;
        }

        public void OnChooserLoad()
        {
            base.Index = 2;

            if (null != _chooserModel && null != _chooserModel.ListOfTables)
                _chooserModel.ListOfTables.Clear();
            #region _model Initialization

            _model = new TablesModel
            {
                Name = "Choose Your Database Objects",
                Question = "_Which database objects do you want to include in your model?",
                Description = "Model Namespace:",
                ClassName = "[Namespace]",
                TableTree = new ObservableCollection<TableTree>
                {
                   new TableTree{ Name = new WPLDBString{Original= "Tables"},
                    ListOfTables =new ObservableCollection<TableModel>(SQLHelper.GetListOfTableModels(_chooserModel == null ? null : _chooserModel.ConnectionString))
                   }
                }
            };

            #endregion

            base.OnPropertyChanged(() => TableTreeModel);
            if (null != _chooserModel) ClassName = string.Format("{0}DataContext", _chooserModel.ConnectionString.InitialCatalog().RemoveSpecialChar());

        }

        public void OnSelectedChanged(IWPLDBString p)
        {
            if ("Tables" == p.Original)
            {
                AddRemoveAllTablesNames(_model.TableTree[0]);
            }
            else
            {
                AddRemoveTableNames(p);
            }
            base.RaiseEvent(Name);
        }

        public bool IsValid
        {
            get
            {
                return null != _chooserModel
                    && null != _chooserModel.ListOfTables
                    && 0 < _chooserModel.ListOfTables.Count
                    && null != _model.ClassName
                    && _model.ClassName.IsNotNullOrNotEmpty()
                    && 0 < _model.ClassName.Length;

            }
        } 
        #endregion

        #region "Properties"

        public string Question
        {
            get
            {
                return _model.Question;
            }
        }

        public string Name
        {
            get
            {
                return _model.Name;
            }
        }

        public string Description
        {
            get
            {
                return _model.Description;
            }
        }

        public string ClassName
        {
            get
            {
                return _model.ClassName;
            }
            set
            {
                if (value != _model.ClassName)
                {
                    _model.ClassName = value;
                    _chooserModel.ClassName = value;
                    base.OnPropertyChanged(() => ClassName);
                    base.RaiseEvent(Name);
                }
            }
        }

        public ObservableCollection<TableTree> TableTreeModel
        {
            get
            {
                return _model.TableTree;
            }

        }

        

        #endregion

        #region "Methods"

        private void AddRemoveTableNames(IWPLDBString name)
        {
            if (null == _chooserModel.ListOfTables)
                _chooserModel.ListOfTables = new List<IWPLDBString>();

            if (_chooserModel.ListOfTables.Contains(name))
                _chooserModel.ListOfTables.Remove(name);
            else
                _chooserModel.ListOfTables.Add(name);


        }

        private void AddRemoveAllTablesNames(TableTree tableTree)
        {
            if (null == _chooserModel.ListOfTables)
                _chooserModel.ListOfTables = new List<IWPLDBString>();

            _chooserModel.ListOfTables.Clear();


            List<TableModel> listOfTables = new List<TableModel>();
            if (null != tableTree && null != tableTree.ListOfTables)
                foreach (var item in tableTree.ListOfTables)
                {
                    if (tableTree.IsSelected) _chooserModel.ListOfTables.Add(item.Name);
                    item.IsSelected = tableTree.IsSelected;
                    listOfTables.Add(item);

                }

            _model.TableTree.Clear();
            tableTree.ListOfTables = new ObservableCollection<TableModel>(listOfTables);
            _model.TableTree.Add(tableTree);
            base.OnPropertyChanged(() => TableTreeModel);

        }

        #endregion
    }

}
